using Microsoft.EntityFrameworkCore;

namespace Universal.Infrastructure.DB;

/// <summary>
/// 模型构建器命名扩展
/// </summary>
public static class ModelBuilderNamingExtensions
{
    /// <summary>
    /// 统一设置表名和字段名的命名约定
    /// </summary>
    public static void ApplyCustomNamingConventions(this ModelBuilder modelBuilder)
    {
        foreach (var entity in modelBuilder.Model.GetEntityTypes())
        {

            // 去掉"App"前缀
            var className = entity.ClrType.Name;
            if (className.StartsWith("App"))
            {
                className = className.Substring(3);
            }
            var tableName = ToSnakeCase(className) + "s";
            entity.SetTableName(tableName);

            // 2. 字段名约定（如全部 snake_case）
            foreach (var property in entity.GetProperties())
            {
                property.SetColumnName(ToSnakeCase(property.Name));
            }

            // 3. 主键、外键等也可处理
            foreach (var key in entity.GetKeys())
            {
                key.SetName(ToSnakeCase(key.GetName() ?? ""));
            }
            foreach (var fk in entity.GetForeignKeys())
            {
                fk.SetConstraintName(ToSnakeCase(fk.GetConstraintName() ?? ""));
            }
            foreach (var index in entity.GetIndexes())
            {
                index.SetDatabaseName(ToSnakeCase(index.GetDatabaseName() ?? ""));
            }
        }
    }

    /// <summary>
    /// PascalCase/CamelCase 转 snake_case
    /// </summary>
    public static string ToSnakeCase(string input)
    {
        if (string.IsNullOrWhiteSpace(input))
            return input;

        var chars = new List<char>();
        for (int i = 0; i < input.Length; i++)
        {
            var c = input[i];
            if (char.IsUpper(c) && i > 0)
            {
                chars.Add('_');
            }
            chars.Add(char.ToLower(c));
        }
        return new string(chars.ToArray());
    }
}